package org.abettor.angleworm.media;

import java.io.IOException;

import javax.media.CaptureDeviceInfo;
import javax.media.Manager;
import javax.media.MediaLocator;
import javax.media.NoDataSourceException;
import javax.media.NoProcessorException;
import javax.media.Processor;
import javax.media.format.UnsupportedFormatException;
import javax.media.protocol.ContentDescriptor;
import javax.media.protocol.DataSource;

/**
 * 媒体捕获程序抽象类
 * @author abettor
 *
 */
public abstract class MediaCapture
{
	private CaptureDeviceInfo device;
	private ContentDescriptor descriptor;
	private Processor processor;

	/**
	 * 通过设备信息，构造一个媒体捕获程序实例
	 * @param device 要执行捕获动作的设备
	 * @param descriptor 要使用内容描述符，为null则保持默认
	 */
	public MediaCapture(CaptureDeviceInfo device, ContentDescriptor descriptor)
	{
		this.device = device;
		this.descriptor = descriptor;
	}

	/**
	 * 开始捕获媒体信息并输出媒体信息
	 * @throws IOException 
	 * @throws InterruptedException 
	 * @throws UnsupportedFormatException 
	 */
	public DataSource getOutputStream() throws IOException, InterruptedException, UnsupportedFormatException
	{
		//	获取媒体处理器，并configure之
		if(device == null)
		{
			return null;
		}
		MediaLocator locator = device.getLocator();
		DataSource dsSrc = null;
		try
		{
			dsSrc = Manager.createDataSource(locator);
		}
		catch (NoDataSourceException e)
		{
			e.printStackTrace();
			return null;
		}
		try
		{
			processor = Manager.createProcessor(dsSrc);
		}
		catch (NoProcessorException e)
		{
			e.printStackTrace();
			return null;
		}
		processor.configure();
		while(processor.getState() != Processor.Configured)
		{
			Thread.sleep(10);
		}

		//	设置内容描述符
		if(descriptor != null)
		{
			processor.setContentDescriptor(descriptor);
		}

		//	调用格式设定抽象方法
		format(processor);

		//	realize媒体处理器并启动之
		processor.realize();
		while(processor.getState() != Processor.Realized)
		{
			Thread.sleep(10);
		}
		processor.start();
		while(processor.getState() != Processor.Started)
		{
			Thread.sleep(10);
		}

		return processor.getDataOutput();
	}

	/**
	 * 停止媒体捕获行为并关闭捕获设备
	 * @throws InterruptedException 
	 */
	public void closeCapture() throws InterruptedException
	{
		if(processor == null)
		{
			return;
		}

		processor.stop();
		if(processor.getState() == Processor.Started)
		{
			Thread.sleep(10);
		}
		processor.close();
		processor = null;
	}

	/**
	 * 对输出的媒体格式进行处理
	 * @param processor 处于Configured状态的Processor实例对象
	 * @throws UnsupportedFormatException
	 */
	protected abstract void format(Processor processor) throws UnsupportedFormatException;
}
